package q1.project.plugin.fastexcel.utils;

import cn.idev.excel.FastExcel;
import cn.idev.excel.support.ExcelTypeEnum;
import cn.idev.excel.write.metadata.style.WriteCellStyle;
import cn.idev.excel.write.metadata.style.WriteFont;
import cn.idev.excel.write.style.HorizontalCellStyleStrategy;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.HorizontalAlignment;

/** Excel 工具类 基于 FastExcel (cn.idev.excel) 封装 */
@Slf4j
public class ExcelUtils {

  /**
   * 导出 Excel 到 HttpServletResponse (Web 下载)
   *
   * @param response 响应对象
   * @param fileName 文件名（不需要后缀）
   * @param sheetName Sheet名称
   * @param clazz 数据类 Class
   * @param data 数据列表
   */
  public static <T> void write(
      HttpServletResponse response,
      String fileName,
      String sheetName,
      Class<T> clazz,
      List<T> data) {
    try {
      response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
      response.setCharacterEncoding("utf-8");
      // 这里URLEncoder.encode可以防止中文乱码
      String encodedFileName =
          URLEncoder.encode(fileName, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
      response.setHeader(
          "Content-disposition", "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");

      FastExcel.write(response.getOutputStream(), clazz)
          .excelType(ExcelTypeEnum.XLSX)
          .sheet(sheetName)
          .registerWriteHandler(getStyleStrategy()) // 使用默认样式
          .doWrite(data);
    } catch (IOException e) {
      log.error("导出Excel异常", e);
      throw new RuntimeException("导出Excel失败");
    }
  }

  /** 导出 Excel 到输出流 */
  public static <T> void write(
      OutputStream outputStream, String sheetName, Class<T> clazz, List<T> data) {
    FastExcel.write(outputStream, clazz)
        .excelType(ExcelTypeEnum.XLSX)
        .sheet(sheetName)
        .registerWriteHandler(getStyleStrategy())
        .doWrite(data);
  }

  /** 获取默认样式策略 */
  private static HorizontalCellStyleStrategy getStyleStrategy() {
    // 表头策略
    WriteCellStyle headWriteCellStyle = new WriteCellStyle();
    WriteFont headWriteFont = new WriteFont();
    headWriteFont.setFontHeightInPoints((short) 12);
    headWriteFont.setBold(true);
    headWriteCellStyle.setWriteFont(headWriteFont);
    headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);

    // 内容策略
    WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
    WriteFont contentWriteFont = new WriteFont();
    contentWriteFont.setFontHeightInPoints((short) 11);
    contentWriteCellStyle.setWriteFont(contentWriteFont);
    contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);

    return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
  }
}
